'''所有App类的基类.

这个类的设计基于自定义的MyFlaskApps的请求.
必须响应网页请求,方法请求,线程监视请求这3种请求.
在本类中分别是getPage,postMethod,askThread三个方法.
其中postMethod是继承的类最可能需要重写的.如果只是简单的回应页面,getPage
不用重写,askThread也不需要.

构造方法中的self._threadDict是线程表{线程名:线程(BaseThread的子类)},
askThread方法就是访问这个表的线程信息.

'''

from flask import render_template

class BaseApp:

  def __init__(self, appname):
    '''通过appname指定应用名字,以后只会访问对应的文件夹'''
    self._appname = appname
    self._threadDict = {} # 线程名称表,key是线程名字符串,value是BaseThread的子类
    return
    
  def getPage(self, page, flaskRequest):
    '''请求一个页面page,传入flask的request参数,返回一个页面.
    如不需要渲染,则不需要重写.
    '''
    return render_template(f'{self._appname}/{page}')
    
  def postMethod(self, methodName, flaskRequest):
    '''请求一个post的结果,请求名为methodName,传入flask的request参数,
    被post上来的data应该是一个{},可以用flaskRequest.form[key]访问,
    本方法返回值应该是一个{}.使用时可以说是必须重写的.
    '''
    return
    
  def askThread(self, threadName):
    '''询问线程状态,一般不需要重写'''
    if threadName in self._threadDict:
      return self._threadDict[threadName].getStatus()
    return {'code': -2, 'error': f'线程{threadName}不存在'}
    
  ### 获取链接的?形式参数,如1.html?a=1&b=2.是后来再加入的方法.返回参数字典
  def _getUrlParams(self, url):
    result = {}
    sp = url.split('?')
    if (len(sp) != 2):
      return result
    params = sp[1].split('&')
    for param in params:
      paramSplit = param.split('=')
      if (len(paramSplit)) < 2:
        continue
      result[paramSplit[0]] = paramSplit[1]
    return result